/**
 * $Id: SGIP12MessageConvertor.java,v 1.50 2006/10/26 09:15:56 martin Exp $
 *
 * Copyright 2006 Skyinfo, Inc. All Rights Reserved.
 */
package com.haoxi.gateway.messageconvertor.impl;

import java.util.Date;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.haoxi.gateway.common.CommonMsgBean;
import com.haoxi.gateway.common.GatewayInfo;
import com.haoxi.gateway.common.INFOConst;
import com.haoxi.gateway.common.Text;
import com.haoxi.gateway.messageconvertor.MessageConvertor;
import com.haoxi.gateway.runner.RunnerMgr;
import com.haoxi.gateway.runner.smscommand.BaseCommandObj;
import com.haoxi.gateway.runner.smscommand.SubmitCmd;
import com.haoxi.gateway.runner.smscommand.SubmitReportCmd;
import com.haoxi.gateway.runner.smscommand.SubmitStatusCmd;
import com.haoxi.gateway.runner.smscommand.UserMOCmd;
import com.haoxi.gateway.sgip12msg.SGIPCommon;
import com.haoxi.gateway.sgip12msg.SGIPDeliverMessage;
import com.haoxi.gateway.sgip12msg.SGIPReportMessage;
import com.haoxi.gateway.sgip12msg.SGIPSubmitMessage;
import com.haoxi.gateway.sgip12msg.SGIPSubmitRepMessage;
import com.haoxi.gateway.sgip12msg.SequenceSower;

/**
 * 参照SGIP1.2协议中定义的消息体结构，实现的消息转换器
 * 
 * Revision History
 * 
 * 2006-6-12,Martin,created it
 */
public class SGIP12MessageConvertor extends MessageConvertor {
    private static final Log log = LogFactory
            .getLog(SGIP12MessageConvertor.class);
    private String protcolVersion;
    private static final String MOBREX = "^((\\+{0,1}86){0,1})(13[0-9]{9}|15[0-9]{9})";
    private static final String SPLITREX = ",";

    /**
     * 构造函数
     */
    public SGIP12MessageConvertor(String gatewayCode) {
        super(gatewayCode);
        this.protcolVersion = INFOConst.SGIP12_VERSION;
    }

    /**
     * 保留字段,stat有用
     */

    private Object reserve;

    /**
     * 根据BaseCommandObj构造网关需要的消息
     * 
     * @param BaseCommandObj obj
     * @return CommonMsgBean 见CommonMsgBean定义
     * @author martin
     */
    public CommonMsgBean convertCMDToCommonMsg(BaseCommandObj obj) {
        CommonMsgBean commonMsgBean = new CommonMsgBean();
        commonMsgBean.setGateWayCode(gatewayCode);
        try {
            if (obj instanceof SubmitCmd) {
                SubmitCmd subCmd = (SubmitCmd) obj;
                String[] userNumber = subCmd.getDestMobile().split(SPLITREX);
                for (int i = 0; i < userNumber.length; i++) {
                    userNumber[i] = formatmobile(userNumber[i]);
                }
                String spNumber = subCmd.getOrgMobile();
                String chargeNumber = formatmobile(subCmd.getFeeMobile());
                GatewayInfo gatewayInfo = RunnerMgr.getInstance()
                        .getGatewayInfo();
                String corpid = gatewayInfo.getIcp_id();
                String serviceType = subCmd.getServiceId();
                byte feeType = Byte.parseByte(subCmd.getFeeType());
                String feeValue = String.valueOf(subCmd.getFeeCode());
                String givenValue = "000000";
                int agentFlag = 0;
                int morelatetoMTFlag = subCmd.getMtFlag();
                int priority = 0;
                Date expireTime = null;
                Date scheduleTime = null;
                int reportFlag = subCmd.getReg_del();
                int tP_pid = subCmd.getTpPId();
                int tpUdhi = subCmd.getTpUdhi();
                int msgCoding = subCmd.getMsgCoding();
                int messageType = 0;
                byte[] messageContent = Text.textToByte(msgCoding, subCmd
                        .getMsgContent());
                String reserve = subCmd.getLinkID();
                if (4 == feeType) {
                    chargeNumber = "000000000000000000000";
                } else if (chargeNumber.equals("000000000000000000000")) {
                    feeType = 4;
                }
                SGIPSubmitMessage submitMsg = new SGIPSubmitMessage(spNumber,
                        chargeNumber, userNumber, corpid, serviceType, feeType,
                        feeValue, givenValue, agentFlag, morelatetoMTFlag,
                        priority, expireTime, scheduleTime, reportFlag, tP_pid,
                        tpUdhi, msgCoding, messageType, messageContent.length,
                        messageContent, reserve);
                SequenceSower.setUnicomSequence(submitMsg);
                log.debug(submitMsg.toString());
                subCmd.setSequence("" + submitMsg.getSrcNodeId()
                        + submitMsg.getTimeStamp() + submitMsg.getSequenceId());
                commonMsgBean.setBody(submitMsg.getBytes());
                commonMsgBean.setReserve(subCmd);
            }
        } catch (Exception ex) {
            log
                    .error(
                            "Exception in SGIP12MessageConvertor.convertCMDToCommonMsg(): Exception",
                            ex);
            commonMsgBean = null;
        }
        return commonMsgBean;
    }

    /**
     * 转换从网关下发的消息,最终转换成BaseCommandObj
     * 
     * @param CommonMsgBean commonMsgBean 包含了网关下发的消息，网关编号
     * @BaseCommandObj 见BaseCommandObj定义
     * @author martin
     */
    public BaseCommandObj convertCommonMsgToCMD(CommonMsgBean commonMsgBean) {
        reserve = commonMsgBean.getReserve();
        int commid = commonMsgBean.getCommid();
        String connName = commonMsgBean.getConnName();
        byte[] body = commonMsgBean.getBody();
        byte[] msgidseq = new byte[12];
        System.arraycopy(body, 0, msgidseq, 0, 12);
        if (SGIPCommon.SGIP_DELIVER == commid) {
            SGIPDeliverMessage deliver = new SGIPDeliverMessage(body);
            UserMOCmd mocmd = new UserMOCmd();
            String sequence = "" + deliver.getSrcNodeId()
                    + deliver.getTimeStamp() + deliver.getSequenceId();
            mocmd.setCommandID(commid);
            mocmd.setCommandLength(body.length + 8);
            mocmd.setConnName(connName);
            mocmd.setDestMobile(deliver.getSPNumber());
            int msgFmt = deliver.getMsgFmt();
            mocmd.setMsgCoding(msgFmt);
            mocmd.setSequence(sequence);
            mocmd.setSpNumber(deliver.getSPNumber());
            String msgContent = Text.getText(msgFmt, deliver.getMsgContent());
            mocmd.setMsgContent(msgContent);
            mocmd.setLinkId(deliver.getReserve());
            mocmd.setMsgId(sequence);
            mocmd.setGateWayCode(gatewayCode);
            mocmd.setOrgMobile(remove86(deliver.getUserNumber()));
            mocmd.setOrgMobileType(INFOConst.TRUE_TYPE);
            mocmd.setReserved(reserve);
            mocmd.setMsgId_bytes(msgidseq);
            return mocmd;
        } else if (SGIPCommon.SGIP_REPORT == commid) {

            SubmitReportCmd report = new SubmitReportCmd();
            SGIPReportMessage reportmsg = new SGIPReportMessage(body);
//            String sequence = "" + reportmsg.getSrcNodeId()
//                    + reportmsg.getTimeStamp() + reportmsg.getSequenceId();
            report.setCommandID(reportmsg.getCommandId());
            report.setCommandLength(body.length + 8);
            report.setConnName(connName);
            report.setDoneTime("");
            report.setGatewayCode(gatewayCode);
            report.setMsgID(reportmsg.getSubmitSequenceNumberStr());
            report.setMsgId_bytes(msgidseq);
            int state = reportmsg.getState();
            if (2 == state) {
                report.setReport(String.valueOf(reportmsg.getErrorCode()));
            } else {
                report.setReport(String.valueOf(reportmsg.getState()));
            }
            report.setSequence(reportmsg.getSubmitSequenceNumberStr());
            report.setUserNumber(remove86(reportmsg.getUserNumber()));
            report.setUserNumberType(reportmsg.getReportType());
            return report;
        } else if (SGIPCommon.SGIP_SUBMIT_RESP == commid) {
            SubmitStatusCmd submitCmd = new SubmitStatusCmd();
            SGIPSubmitRepMessage repmsg = new SGIPSubmitRepMessage(body);
            String sequence = "" + repmsg.getSrcNodeId()
                    + repmsg.getTimeStamp() + repmsg.getSequenceId();
            submitCmd.setCommandID(repmsg.getCommandId());
            submitCmd.setCommandLength(body.length + 8);
            submitCmd.setMsgID(sequence);
            submitCmd.setStatus(String.valueOf(repmsg.getResult()));
            submitCmd.setSequence(sequence);
            submitCmd.setReserved(reserve);
            return submitCmd;
        }
        return null;
    }

    /**
     * @return Returns the protcolVersion.
     */
    public String getProtcolVersion() {
        return protcolVersion;
    }

    // 将所有的手机号码格式化为8613XXXXXXXXX形式或86159XXXXXXXX形式的
    protected String formatmobile(String phoneNum) {

        Pattern p1 = Pattern.compile(MOBREX);
        Matcher m1 = p1.matcher(phoneNum);
        String result = "";
        if (m1.matches() && phoneNum.length() == 11) {
            result = "86".concat(phoneNum);
        } else if (m1.matches() && phoneNum.indexOf("+") != -1) {
            result = phoneNum.replaceAll("\\+", "");
        } else if (phoneNum.equals("000000000000000000000")) {
            result = phoneNum;
        } else {
            throw new IllegalArgumentException("invalid mobile");
        }
        return result;
    }

    // 去掉+86和86
    protected String remove86(String phoneNum) {

        Pattern p1 = Pattern.compile(MOBREX);
        Matcher m1 = p1.matcher(phoneNum);
        if (m1.matches()) {
            Pattern p2 = Pattern.compile("^((\\+{0,1}86){0,1})");
            Matcher m2 = p2.matcher(phoneNum);
            StringBuffer sb = new StringBuffer();
            while (m2.find()) {
                m2.appendReplacement(sb, "");
            }
            m2.appendTail(sb);
            return sb.toString();

        }
        return phoneNum;
    }

}
